package com.pms.util;


import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.pms.cache.utils.RedisCacheUtil;
import com.pms.entity.*;
import com.pms.exception.RRException;
import com.pms.service.IEstateDoorCardService;
import com.pms.service.IEstateDoorLockService;
import com.pms.service.IEstateLockCardService;
import com.pms.service.IOpenDoorRecordService;
import com.pms.util.httpUtil.HttpClientUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.logging.SimpleFormatter;

/**
 * 大豪设备 请求工具类
 * Created by Administrator on 2017/8/22.
 */
@Component
public class DaHaoLockUtil {
    @Autowired
    IEstateDoorLockService estateDoorLockService;
    @Autowired
    IEstateDoorCardService estateDoorCardService;
    @Autowired
    IEstateLockCardService estateLockCardService;
    @Autowired
    RedisCacheUtil redisCacheUtil;
    @Autowired
    private IOpenDoorRecordService openDoorRecordService;
    @Value("${daHao.service.warName}")
    private String serviceWarName;

    private Logger logger = LoggerFactory.getLogger(getClass());

    public void main(String arg[]) throws Exception {

    }

    public String readDaHaoServiceWarName() {
        if (StringUtils.isBlank(serviceWarName)) {
            throw new RRException("大豪服务名称为空");
        }
        return "/" + serviceWarName;
    }

    /**
     * 查询设备是否在线
     *
     * @param eqSn   设备id
     * @param doorId 门id
     * @return null-未查询到设备，true-设备在线，false-设备不在线
     */
    public Map<String, Object> checkDeviceIsOnLine(String eqSn, Long doorId) {
        Map<String, Object> returnMap = new HashMap<String, Object>();
        returnMap.put("isOnLine", false);
        Wrapper<EstateDoorLock> wp = new EntityWrapper<EstateDoorLock>();
        wp.eq("factory_code", "daHao");
        if (StringUtils.isNotBlank(eqSn)) {
            wp.eq("eq_sn", eqSn);
        }
        if (doorId != null) {
            wp.eq("door_id", doorId);
        }
        EstateDoorLock doorLock = estateDoorLockService.selectOne(wp);
        if (doorLock == null) {
            return null;
        }
        returnMap.put("eqSn", doorLock.getEqSn());
        returnMap.put("factoryServiceUrl", doorLock.getFactoryServiceUrl());
        returnMap.put("eqPswd", doorLock.getEqKey());
        returnMap.put("doorId", doorLock.getDoorId());
        StringBuilder url = new StringBuilder("http://").append(doorLock.getFactoryServiceUrl()).append(readDaHaoServiceWarName()).append("/app/checkDeviceOnLineStatus");
        StringBuilder param = new StringBuilder("DEVICE_ID=").append(doorLock.getEqSn());
        JSONObject resultJson = HttpClientUtil.doPost(url.toString(), param.toString());
        try {
            String dataStr = resultJson.getString("data");
            if (dataStr.equals("1")) {
                returnMap.put("isOnLine", true);
                return returnMap;
            } else {
                JSONObject data = JSONObject.parseObject(resultJson.getString("data"));
                if (data.getString("status").equals("1")) {
                    returnMap.put("isOnLine", true);
                    return returnMap;
                } else {
                    return returnMap;
                }
            }
        } catch (net.sf.json.JSONException ex) {
            return returnMap;
        } catch (Exception ex) {
            return returnMap;
        }
    }

    /**
     * 远程 下发10张卡片
     *
     * @param eqId 设备id
     * @param tag  true是/false否重发
     */
    public void sendTenCard(String eqId, boolean tag) {
        Map<String, Object> lockMap = checkDeviceIsOnLine(eqId, null);
        if (lockMap != null && lockMap.get("isOnLine").toString().equals("true")) {
            List<EstateLockCard> lockCardList = null;
            try {
                lockCardList = JSONArray.parseArray(redisCacheUtil.getVlue("estateLockCard:selectListByEqSn:" + eqId.trim()).toString(), EstateLockCard.class);
            } catch (NullPointerException ex) {
                lockCardList = null;
            }
            if (lockCardList == null || lockCardList.isEmpty()) {
                lockCardList = estateLockCardService.selectListByEqSn(eqId);
            }
            if (lockCardList != null && !lockCardList.isEmpty()) {
                Integer cardSize = lockCardList.size();
                Integer sendCardNum = 0;
                StringBuilder sendCardNo = new StringBuilder("");
                StringBuilder cardValidDate = new StringBuilder("");
                List<EstateDoorCard> okCardList = new ArrayList<EstateDoorCard>();
                List<String> okCardNuList = new ArrayList<String>();
                List<EstateLockCard> newLockCardList = new ArrayList<EstateLockCard>();
                SimpleDateFormat sdFormat = new SimpleDateFormat("yyyyMMddHHmmss");
                if (cardSize < 11) {
                    if (tag) {// 发卡失败
                        for (int x = 0; x < cardSize; x++) {
                            sendCardNo.append(lockCardList.get(x).getCardNumSixteen());
                            cardValidDate.append(sdFormat.format(lockCardList.get(x).getValidTime()));
                            ++sendCardNum;
                        }
                    }
                    if (!tag) {// 发卡成功  不再继续发卡
                        for (int x = 0; x < cardSize; x++) {
                            EstateDoorCard okCard = new EstateDoorCard();
                            okCard.setCreateTime(new Date());
                            okCard.setUnitName(lockCardList.get(x).getUnitName());
                            okCard.setUnitId(lockCardList.get(x).getUnitId());
                            okCard.setDoorName(lockCardList.get(x).getDoorName());
                            okCard.setDoorId(lockCardList.get(x).getDoorId());
                            okCard.setCommunityName(lockCardList.get(x).getCommunityName());
                            okCard.setCommunityId(lockCardList.get(x).getCommunityId());
                            okCard.setCardNumTen(lockCardList.get(x).getCardNumTen());
                            okCard.setCardNumSixteen(lockCardList.get(x).getCardNumSixteen());
                            okCard.setValidTime(lockCardList.get(x).getValidTime());
                            okCardList.add(okCard);
                            okCardNuList.add(lockCardList.get(x).getCardNumSixteen());
                        }
                    }
                }
                if (cardSize > 10) {
                    if (tag) {// 发卡失败
                        for (int x = 0; x < 10; x++) {
                            sendCardNo.append(lockCardList.get(x).getCardNumSixteen());
                            cardValidDate.append(sdFormat.format(lockCardList.get(x).getValidTime()));
                            ++sendCardNum;
                        }
                    }
                    if (!tag) {// 发卡成功 继续发卡
                        for (int x = 0; x < 10; x++) {
                            EstateDoorCard okCard = new EstateDoorCard();
                            okCard.setCreateTime(new Date());
                            okCard.setUnitName(lockCardList.get(x).getUnitName());
                            okCard.setUnitId(lockCardList.get(x).getUnitId());
                            okCard.setDoorName(lockCardList.get(x).getDoorName());
                            okCard.setDoorId(lockCardList.get(x).getDoorId());
                            okCard.setCommunityName(lockCardList.get(x).getCommunityName());
                            okCard.setCommunityId(lockCardList.get(x).getCommunityId());
                            okCard.setCardNumTen(lockCardList.get(x).getCardNumTen());
                            okCard.setCardNumSixteen(lockCardList.get(x).getCardNumSixteen());
                            okCard.setValidTime(lockCardList.get(x).getValidTime());
                            okCardList.add(okCard);
                            okCardNuList.add(lockCardList.get(x).getCardNumSixteen());
                        }
                        // 继续发卡 发10张
                        for (int x = 10; x < cardSize; x++) {
                            if (x < 20) {
                                sendCardNo.append(lockCardList.get(x).getCardNumSixteen());
                                cardValidDate.append(sdFormat.format(lockCardList.get(x).getValidTime()));
                                ++sendCardNum;
                            }
                            newLockCardList.add(lockCardList.get(x));
                        }
                    }
                }
                if (!tag) {
                    //删除已尊在下发记录的卡
                    estateDoorCardService.delete(new EntityWrapper<EstateDoorCard>().eq("door_id", lockMap.get("doorId")).in("card_num_sixteen", okCardNuList));
                    estateDoorCardService.insertBatch(okCardList);
                    estateLockCardService.delete(new EntityWrapper<EstateLockCard>().eq("eq_sn", eqId).in("card_num_sixteen", okCardNuList));
                    if (!newLockCardList.isEmpty()) {//发卡成功则保存新的
                        redisCacheUtil.saveAndUpdate("estateLockCard:selectListByEqSn:" + eqId.trim(), newLockCardList, 10);
                    }
                }
                if (sendCardNum > 0) {
                    StringBuilder url = new StringBuilder("http://").append(lockMap.get("factoryServiceUrl")).append(readDaHaoServiceWarName()).append("/app/serviceAddKey");
                    StringBuilder param = new StringBuilder("DEVICE_ID=").append(lockMap.get("eqSn"));//设备id
                    param.append("&DEVICEPSW=").append(lockMap.get("eqPswd"));//设备密码
                    param.append("&KEYTYPE=3");//钥匙类型
                    param.append("&DATE=").append(cardValidDate.toString());//钥匙有效期
                    param.append("&KEYID=").append(sendCardNo.toString());//钥匙id
                    param.append("&KEYCOUNT=").append(sendCardNum);//钥匙数量
                    redisCacheUtil.saveAndUpdate("estateLockCard:sendFiveHundredCardRequestTime:" + eqId.trim(), System.currentTimeMillis(), 10);
                    HttpClientUtil.doPost(url.toString(), param.toString());
                } else {
                    sendTenCard(eqId, true);
                }
            }//验证是否 有卡片可发
        }// 验证设备是否在线
    }

    /**
     * 远程 下发500张卡片，分多次下发，每次下发20张卡片
     *
     * @param lockMap      设备信息
     * @param lockCardList 卡片集合
     */
    public void sendFiveHundredCard(Map<String, Object> lockMap, List<EstateLockCard> lockCardList) {
        if (lockMap != null && lockMap.get("isOnLine").toString().equals("true")) {
            if (lockCardList != null && !lockCardList.isEmpty()) {
                Integer sendCardNum = 0;
                StringBuilder sendCardNo = new StringBuilder("");
                StringBuilder cardValidDate = new StringBuilder("");
                SimpleDateFormat sdFormat = new SimpleDateFormat("yyyyMMddHHmmss");
                for (int x = 0; x < lockCardList.size(); x++) {
                    sendCardNo.append(lockCardList.get(x).getCardNumSixteen());
                    cardValidDate.append(sdFormat.format(lockCardList.get(x).getValidTime()));
                    ++sendCardNum;
                }
                if (sendCardNum > 0) {
                    StringBuilder url = new StringBuilder("http://").append(lockMap.get("factoryServiceUrl")).append(readDaHaoServiceWarName()).append("/app/serviceAddKey");
                    StringBuilder param = new StringBuilder("DEVICE_ID=").append(lockMap.get("eqSn"));//设备id
                    param.append("&DEVICEPSW=").append(lockMap.get("eqPswd"));//设备密码
                    param.append("&KEYTYPE=3");//钥匙类型
                    param.append("&DATE=").append(cardValidDate.toString());//钥匙有效期
                    param.append("&KEYID=").append(sendCardNo.toString());//钥匙id
                    param.append("&KEYCOUNT=").append(sendCardNum);//钥匙数量
                    param.append("&IMPORTFLAG=").append(1);//导入标志（非必填项，0：直接发卡 1：框架导入卡片，采用POST方式请求，如果导入卡片多余1000张，建议连续提交多次，导入前需判断设备是否在线）
                    url.append("?").append(param.toString());
                    logger.info("远程发卡500张=================");
                    logger.info(url.toString());
                    logger.info("=================远程发卡500张");
                    HttpClientUtil.doPost(url.toString(), "");
                }
            }//判断卡片是否下发
        }//判断设备是否在线
    }

    /**
     * AB类回调 框架内发卡成功添加发卡记录
     *
     * @param eqId
     * @param sixteenCards
     */
    public void sendCardCallBackOkToAddRecord(String eqId, List<String> sixteenCards) {
        Wrapper<EstateLockCard> lockCardWp = new EntityWrapper<EstateLockCard>();
        lockCardWp.eq("eq_sn", eqId);
        lockCardWp.in("card_num_sixteen", sixteenCards);
        List<EstateLockCard> lockCardList = estateLockCardService.selectList(lockCardWp);
        if (lockCardList != null && !lockCardList.isEmpty()) {
            List<EstateDoorCard> okCardList = new ArrayList<EstateDoorCard>();
            List<EstateDoorCard> editCardList = new ArrayList<EstateDoorCard>();
            Wrapper<EstateDoorCard> existDoorCardWp = new EntityWrapper<EstateDoorCard>();
            existDoorCardWp.eq("door_id", lockCardList.get(0).getDoorId());
            existDoorCardWp.in("card_num_sixteen", sixteenCards);
            List<EstateDoorCard> existDoorCardList = estateDoorCardService.selectList(existDoorCardWp);
            Map<String, Object> existDoorCardMap = new HashMap<String, Object>();
            if (existDoorCardList != null && !existDoorCardList.isEmpty()) {
                for (int y = 0; y < existDoorCardList.size(); y++) {
                    existDoorCardMap.put(existDoorCardList.get(y).getCardNumSixteen(), existDoorCardList.get(y));
                }
            }
            for (int x = 0; x < lockCardList.size(); x++) {
                EstateDoorCard okCard = (EstateDoorCard) existDoorCardMap.get(lockCardList.get(x));
                if (okCard == null) {
                    okCard = new EstateDoorCard();
                    okCard.setValidTime(lockCardList.get(x).getValidTime());
                    okCard.setCardNumSixteen(lockCardList.get(x).getCardNumSixteen());
                    okCard.setCardNumTen(lockCardList.get(x).getCardNumTen());
                    okCard.setCommunityId(lockCardList.get(x).getCommunityId());
                    okCard.setCommunityName(lockCardList.get(x).getCommunityName());
                    okCard.setDoorId(lockCardList.get(x).getDoorId());
                    okCard.setDoorName(lockCardList.get(x).getDoorName());
                    okCard.setUnitId(lockCardList.get(x).getUnitId());
                    okCard.setUnitName(lockCardList.get(x).getUnitName());
                    okCard.setCreateTime(new Date());
                    okCardList.add(okCard);
                }
                if (okCard != null) {
                    okCard.setCreateTime(new Date());
                    okCard.setValidTime(lockCardList.get(x).getValidTime());
                    editCardList.add(okCard);
                }
            }
            estateLockCardService.delete(lockCardWp);
            if (!okCardList.isEmpty()) {
                estateDoorCardService.insertBatch(okCardList);
                estateDoorCardService.clearPreKeyCache("estateUnitCard");
            }
            if (!editCardList.isEmpty()) {
                estateDoorCardService.updateBatchById(editCardList);
            }
        }
    }

    /**
     * AB类回调 框架内发卡成功添加发卡记录
     * @param eqId
     * @param sixteenCards
     */
    public void saveSendCardRecordByFunction(String eqId, List<String> sixteenCards) {
        if(sixteenCards!=null){
            StringBuilder cardNumStr = null;
            Long lockCardIdStart =null;
            EstateDoorCard idDoorCard = null;
            for(int x=0;x<sixteenCards.size();x++){
                if(cardNumStr == null){
                    idDoorCard = new EstateDoorCard();
                    lockCardIdStart = idDoorCard.returnIdLong();
                    cardNumStr= new StringBuilder().append("'").append(sixteenCards.get(x));
                }
                if(cardNumStr != null){
                    idDoorCard.returnIdLong();
                    cardNumStr.append(",").append(sixteenCards.get(x));
                }
            }
            if(cardNumStr!=null){
                cardNumStr.append("'");
                estateDoorCardService.saveSendCardRecordByFunction(eqId,cardNumStr.toString(),lockCardIdStart);
            }
        }
    }
    /**
     * AB类回调 框架内发卡成功添加发卡记录
     * @param eqId
     * @param sixteenCards
     */
    public void saveSendCardRecordByFunction(String eqId, String sixteenCards,Long lockCardIdStart) {
        estateDoorCardService.saveSendCardRecordByFunction(eqId,sixteenCards,lockCardIdStart);
    }
    /**
     * AC类回调 框架内发卡成功添加发卡记录
     *
     * @param eqId
     */
    public void sendCardCallBackOkToAddRecord(String eqId) {
        Wrapper<EstateLockCard> lockCardWp = new EntityWrapper<EstateLockCard>();
        lockCardWp.eq("eq_sn", eqId);
        List<EstateLockCard> lockCardList = estateLockCardService.selectList(lockCardWp);
        List<String> sixteenCards = new ArrayList<String>();
        for (int x = 0; x < lockCardList.size(); x++) {
            sixteenCards.add(lockCardList.get(x).getCardNumSixteen());
        }
        if (lockCardList != null && !lockCardList.isEmpty()) {
            List<EstateDoorCard> okCardList = new ArrayList<EstateDoorCard>();
            List<EstateDoorCard> editCardList = new ArrayList<EstateDoorCard>();
            Wrapper<EstateDoorCard> existDoorCardWp = new EntityWrapper<EstateDoorCard>();
            existDoorCardWp.eq("door_id", lockCardList.get(0).getDoorId());
            existDoorCardWp.in("card_num_sixteen", sixteenCards);
            List<EstateDoorCard> existDoorCardList = estateDoorCardService.selectList(existDoorCardWp);
            Map<String, Object> existDoorCardMap = new HashMap<String, Object>();
            if (existDoorCardList != null && !existDoorCardList.isEmpty()) {
                for (int y = 0; y < existDoorCardList.size(); y++) {
                    existDoorCardMap.put(existDoorCardList.get(y).getCardNumSixteen(), existDoorCardList.get(y));
                }
            }
            for (int x = 0; x < lockCardList.size(); x++) {
                EstateDoorCard okCard = (EstateDoorCard) existDoorCardMap.get(lockCardList.get(x));
                if (okCard == null) {
                    okCard = new EstateDoorCard();
                    okCard.setValidTime(lockCardList.get(x).getValidTime());
                    okCard.setCardNumSixteen(lockCardList.get(x).getCardNumSixteen());
                    okCard.setCardNumTen(lockCardList.get(x).getCardNumTen());
                    okCard.setCommunityId(lockCardList.get(x).getCommunityId());
                    okCard.setCommunityName(lockCardList.get(x).getCommunityName());
                    okCard.setDoorId(lockCardList.get(x).getDoorId());
                    okCard.setDoorName(lockCardList.get(x).getDoorName());
                    okCard.setUnitId(lockCardList.get(x).getUnitId());
                    okCard.setUnitName(lockCardList.get(x).getUnitName());
                    okCard.setCreateTime(new Date());
                    okCardList.add(okCard);
                }
                if (okCard != null) {
                    okCard.setCreateTime(new Date());
                    okCard.setValidTime(lockCardList.get(x).getValidTime());
                    editCardList.add(okCard);
                }
            }
            estateLockCardService.delete(lockCardWp);
            if (!okCardList.isEmpty()) {
                estateDoorCardService.insertBatch(okCardList);
                estateDoorCardService.clearPreKeyCache("estateUnitCard");
            }
            if (!editCardList.isEmpty()) {
                estateDoorCardService.updateBatchById(editCardList);
            }
        }
    }

    /**
     * 添加开门记录统计
     *
     * @param eqSn 设备id
     * @param date 开门时间
     */
    public void addOpenDoorRecord(String eqSn, Date date) {
        EstateDoorLock doorLock = estateDoorLockService.selectOne(new EntityWrapper<EstateDoorLock>().eq("eq_sn", eqSn).eq("factory_code", "daHao"));
        if (doorLock != null) {//未绑定的设备 不做统计
            if (openDoorRecordService.judgeIsExistRecord(doorLock.getDoorId())) {
                openDoorRecordService.addOpenNumByDoorId(doorLock.getDoorId(),date );//添加开门次数
            } else {
                OpenDoorRecord record = new OpenDoorRecord();
                record.setDoorId(doorLock.getDoorId());
                record.setConmunityId(doorLock.getConmunityId());
                record.setAgencyId(doorLock.getAgencyId());
                record.setOpenNum(1L);
                record.setLastOpenTime(date);
                openDoorRecordService.insert(record);//添加记录
            }
        }
    }

    public void saveOpenDoorNumBySqlFunction(String eqSn) {
        openDoorRecordService.saveOpenDoorNumBySqlFunction(eqSn,BaseModel.returnStaticIdLong());
    }




}
